//
//  IMNewCarModel.h
//  BleTestDemo
//
//  Created by cjg on 2019/9/3.
//  Copyright © 2019 cjg. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "IMFunction.h"
#import "IM_NewMessageFactory.h"
#import "IM_NewMessageCoder.h"
#import "KSTimeFormatter.h"

/*
 设备号：
 app：0x02
 l9:0x32
 vx:0x21
 vx控制器：0x22
 vx蓝牙版：0x23
 */

/*
 * 通道列表
 */
typedef NS_ENUM(NSInteger, CarChannelList) {
    CarChannelConnect = 0,           // 连接通道
    CarChannelCheck = 1,             // 检测及测试通道
    CarChannelProductMessage = 2,    // 产品信息通道
    CarChannelCarControll = 3,       // 车辆控制通道
    CarChannelCarFile = 4,           // 文件系统通道
    CarChannelCarMemory = 5,         // 车辆存储通道
    CarChannelCarBleSetting = 6,     // ble设置通道
};
/*
 * 0.连接通道
 */
typedef NS_ENUM(NSInteger, CarConnectChannel) {
    CarConnectChannelLine = 0,             // 线路查询
    CarConnectChannelVersion = 1,          // 协议版本号
    CarConnectChannelSafe = 2,             // 安全连接
};

/*
 * 1.检测及测试通道 -- app用不到
 */
typedef NS_ENUM(NSInteger, CarCheckChannel) {
    CarCheckChannelPart1 = 1,               // 布尔信号
    CarCheckChannelPart2 = 2,               // 普通信号
    CarCheckChannelPart3 = 3,               // 线性的普通信号增 益或零点 自动校准
    CarCheckChannelPart4 = 4,               // 线性的普通信号增 益及零点 手动校准
    CarCheckChannelPart5 = 5,               // 参数设置
    CarCheckChannelPart6 = 6,               // 自动或半 自动/测试/ 校准/适应/ 学习
};

/*
 * 2.产品信息通道
 */
typedef NS_ENUM(NSInteger, ProductMessageChannel) {
    ProductMessageChannelType = 1,                  // 产品型号及特征
    ProductMessageChannelCarSN = 2,                 // 产品整体SN
    ProductMessageChannelBatterySN = 3,             // 电池 SN
    ProductMessageChannelMotorSN = 4,               // 电机 SN
    ProductMessageChannelBatteryCapacity = 5,       // 电池总容量
    ProductMessageChannelFirmwareAndDeviceNum = 6,  // 固件版本及设备号获取
    ProductMessageChannelRatedVoltage = 7,          // 产品额定电压
    ProductMessageChannelRatedPower = 8,            // 产品额定功率
    ProductMessageChannelMaxSpeed = 9,              // 设计最高时速
    ProductMessageChannelRechargeMileage = 10,      // 设计续航里程
    ProductMessageChannelDeviceID = 11,             // 设备唯一ID
    ProductMessageChannelFactoryMessage = 12,       // 产品制造商信息
    ProductMessageChannelActivation = 13,           // 设备激活
    ProductMessageChannelHardwareBind = 14,         // 设备硬件绑定信息
    ProductMessageChannelSoftBind = 15,             // 设备软件绑定信息
    ProductMessageChannelFirmwareMessage = 16,      // 固件升级信息
    ProductMessageChannelHardwareVersion = 17,      // 硬件版本号
};

/*
 * 3.控制通道
 */
typedef NS_ENUM(NSInteger, CarControllChannel) {
    CarControllChannelSending = 1,            // 关机、重启、休眠、唤醒 主机发送请求
    CarControllChannelCommit = 2,             // 关机、重启、休眠、唤醒 主机确认请求
    CarControllChannelReview = 3,             // 恢复出厂设置
    CarControllChannelUploadState = 4,        // 启动固件升级 、 读取固件升级状态
    CarControllChannelNeedUpload = 5,         // 强制固件升级
    CarControllChannelLockAlarm = 6,          // 设备锁定及报警
};

/*
 * 4.文件操作通道
 */
typedef NS_ENUM(NSInteger, CarFileChannel) {
    CarFileChannelOpen = 1,            // 打开文件
    CarFileChannelWrite = 2,           // 读写文件
    CarFileChannelCheck = 3,           // 校验文件
    CarFileChannelCloose = 4,          // 关闭文件
    CarFileChannelRead = 5,            // 读取文件信息
    CarFileChannelDelegate = 6,        // 删除文件
    CarFileChannelResetName = 7,       // 重命名文件
    CarFileChannelGetFileList = 8,     // 获取文件列表
};

/*
 * 5.存储设备操作通道
 */
typedef NS_ENUM(NSInteger, CarMemoryChannel) {
    CarMemoryChannelSize = 1,     // 总容量及剩余容量
    CarMemoryChannelDelegate = 2, // 擦除并格式化
};

/*
 * 6.蓝牙配置通道
 */
typedef NS_ENUM(NSInteger, CarBleSettingChannel) {
    CarBleSettingChannelName = 1,      // 蓝牙名称
    CarBleSettingChannelPassword = 2,  // 蓝牙密码
    CarBleSettingChannelMAC = 3,       // 蓝牙Mac地址
    CarBleSettingCheckBlePassword = 4, // 验证蓝牙密码

};

// 日期
typedef struct{  // 4 bytes
    uint32_t year   : 6; // 2020-2084
    uint32_t month  : 4; // 1-12
    uint32_t day    : 5; // 1-31
    uint32_t hour   : 5; // 0-23
    uint32_t minute : 6; // 0-59
    uint32_t second : 6; // 0-59
} __attribute__((packed)) NEW_CAR_DATE;

// 标准组错误代码
typedef NS_ENUM(int, StandardErrorCode) {
    StandardErrorCodeRepeatFail = -2,     // 重试后失败
    StandardErrorCodeTimeOut = -1 ,       // 消息超时
    StandardErrorCodeSuccess = 0,         // 无错误，且已生效
    StandardErrorCodeParamError = 1 ,     // 参数错误
    StandardErrorCodeNotSupport = 2 ,     // 目标设备不支持此操作
    StandardErrorCodeNotAllowed = 3 ,     // 当前状态不允许进行此操作
    StandardErrorCodeNotOperation = 4 ,   // 无操作权限
    StandardErrorCodeExecutionError = 5 , // 内部执行错误
};

// 文件操作错误代码
typedef NS_ENUM(int, StandardFileErrorCode) {
    StandardFileErrorCodeRepeatFail = -2,            // 重试后失败
    StandardFileErrorCodeTimeOut = -1 ,              // 消息超时
    StandardFileErrorCodeSuccess = 0,                // 操作成功
    StandardFileErrorCodeNotFile = 1 ,               // 文件不存在
    StandardFileErrorCodeNotSupport = 2 ,            // 不支持此操作
    StandardFileErrorCodeConflict = 3 ,              // 操作冲突
    StandardFileErrorCodeOutUpperLimit = 4 ,         // 同时打开的文件数量已达上限
    StandardFileErrorCodeHandleError = 5 ,           // 非法句柄
    StandardFileErrorCodeSystemError = 6 ,           // 文件系统错误
    StandardFileErrorCodeFileBottomError = 7,        // 文件底层 IO 错误
    StandardFileErrorCodeParamError = 8 ,            // 输入参数错误
    StandardFileErrorCodeInternalProgramError = 9 ,  // 系统内部程序错误
    StandardFileErrorCodeNotAllowed = 10 ,           // 当前状态不允许相应操作
    StandardFileErrorCodeNotOperation = 11 ,         // 无操作权限
    StandardFileErrorCodeErrorOther = 12 ,           // 其他错误
};

extern NSString * const StandardErrorCodeDomain;

typedef void(^IMNewCarModelCompletionBlock)(NSError *error, NSData *responseData);
typedef void(^IMNewCarModelSettingSuccessBlock)(void);
typedef void(^IMNewCarModelSettingFailBlock)(NSError *error);

@interface IMNewCarModel : NSObject

// 标准组公共属性
@property (nonatomic , strong)NSString *lx_bleName;
@property (nonatomic , strong)NSString *lx_sn;
// 安全连接随机密码
@property (nonatomic, strong)NSData *randomCode;

// 蓝牙连接密码
@property (nonatomic, strong)NSString *blePassword;

@property (nonatomic , assign)uint8_t mainSeries; // 主系列
@property (nonatomic , assign)uint8_t subSeries;  // 子系列
@property (nonatomic , assign)uint8_t deviceType; // 具体型号
@property (nonatomic , assign)uint8_t carBatch;    // 批次特征
@property (nonatomic , assign)uint8_t portFeature; // 接口特征
@property (nonatomic , assign)uint8_t carTypeReserved; // 产品型号及特征保留
@property (nonatomic , strong)NSString *LX_CarType; // 产品型号

@property (nonatomic , strong)NSString *batterySN;
@property (nonatomic , strong)NSString *motorSN;
@property (nonatomic , assign)uint16_t batterySize;
@property (nonatomic , strong)NSString *carVersion;
@property (nonatomic , strong)NSString *carBootloaderVersion; // 引导程序版本号
@property (nonatomic, strong) NSMutableArray *versionData;    //软件版本号字典
@property (nonatomic, strong) NSMutableArray *hwVersionData;  //硬件版本号字典
@property (nonatomic, strong) NSMutableArray *deviceData;     //设备唯一ID字典
@property (nonatomic , assign)uint16_t ratedVoltage;
@property (nonatomic , assign)uint16_t ratedPower;
@property (nonatomic , assign)uint16_t maxSpeed;              // 设计最高限速
@property (nonatomic , assign)uint16_t rechargeMileage;
@property (nonatomic , strong)NSString *deviceID;
@property (nonatomic , copy)NSString *factoryDate;     // 车辆生产日期
@property (nonatomic , assign)uint32_t factoryCode;    // 车辆生产厂商代号
@property (nonatomic , copy)NSString *activationDate;  // 车辆激活时间

// 专用组公有属性
@property (nonatomic , assign) int32_t recordCount;          // 骑行记录总数
@property (nonatomic , assign) double currentSpeed;          // 当前车速
@property (nonatomic , assign) double currentMaxSpeed;       // 最大速度
@property (nonatomic , assign) double speedControl;          // 动态限速值
@property (nonatomic , assign) double thisTime_mileage;      // 本次里程
@property (nonatomic , assign) double thisTime_rideTime;     // 本次骑行时长
@property (nonatomic , assign) double averageSpeed;          // 本次平均速度
@property (nonatomic , assign) double remainder_mileage;     // 剩余里程
@property (nonatomic , assign) double total_mileage;         // 总里程
@property (nonatomic , assign) double total_energy;          // 总能耗
@property (nonatomic , assign) double total_recovery;        // 总回收能量
@property (nonatomic , assign) double total_rideTime;        // 总骑行时长
@property (nonatomic , assign) double total_runTime;         // 总开机时长
@property (nonatomic , assign) double current_current;       // 当前电流
@property (nonatomic , assign) double maxCurrent;            // 最高电流
@property (nonatomic , assign) double current_voltage;       // 当前电压
@property (nonatomic , assign) double power;                 // 当前功率
@property (nonatomic , assign) double energy;                // 当前能耗
@property (nonatomic , assign) double battery_percent;       // 剩余电量
@property (nonatomic , assign) double mos_temperature;       // 控制器温度
@property (nonatomic , assign) double motor_temperature;     // 电机温度
@property (nonatomic , assign) double battery_temperature;   // 电池温度


@property (nonatomic , assign) double power_on_time;        // 开机时长





@property (nonatomic, strong) NSMutableArray<NSNumber *> *powers;       // 功率数组
@property (nonatomic, strong) NSMutableArray<NSNumber *> *speeds;       // 速度数组
@property (nonatomic, strong) NSMutableArray<NSNumber *> *temperatures; // 温度数组
@property (nonatomic, strong) NSMutableArray *tripEnergies;             // 能耗数组


- (void)addValue:(double)value toArray:(NSMutableArray *)array limited:(BOOL)limited;

// 安全连接读取
- (void)getSafeChannelWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 安全连接写入
- (void)setSafePasswordWithPassword:(NSData *)password successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取产品型号及特征
- (void)getProductMessageCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入产品型号和批次特征
- (void)setProductMessageWithCarType:(uint16_t)carType batch:(uint16_t)batch successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取车身sn
- (void)getCarSNWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入车身sn
- (void)setCarSNWithSN:(NSString *)sn target:(uint8_t)target successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取电池sn
- (void)getCarBatterySNWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入电池sn
- (void)setCarBatterySNWithSN:(NSString *)sn successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取电机sn
- (void)getCarMotorSNWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入电机sn
- (void)setCarMotorSNWithSN:(NSString *)sn  successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取电池总容量
- (void)getCarBatterySizeWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入电池总容量
- (void)setCarBatterySizeWithSize:(uint16_t)size successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取软件固件版本号和设备号
- (void)getCarFirmwareAndDeviceNumWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;
// 获取硬件固件版本号和设备号
- (void)getCarHWFirmwareAndDeviceNumWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;
// 获取产品额定电压
- (void)getCarRatedVoltageWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入额定电压
- (void)setCarRatedVoltageWithPower:(uint16_t)voltage successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取产品额定功率
- (void)getCarRatedPowerWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入产品额定功率
- (void)setCarRatedPowerWithPower:(uint16_t)power successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取设计最高限速
- (void)getCarMaxSpeedWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入设计最高限速
- (void)setCarMaxSpeedWithSpeed:(uint16_t)speed successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取续航里程
- (void)getCarRechargeMileageWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入续航里程
- (void)setCarRechargeMileageWithMileage:(uint16_t)mile successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取设备唯一ID
- (void)getCarDeviceIDWithTargetDevice:(uint8_t)device compleBlock:(void (^)(NSError *error, NSString *deviceId))compleBlock;

// 获取产品制造商信息
- (void)getDeviceFactoryMessageWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;
// 写入产品制造商信息
- (void)sendDeviceFactoryMessageWithDate:(NSDate *)date factoryCode:(uint32_t)Factory successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取设备激活状态
- (void)getCarDeviceActivationStatuSsuccessBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;
// 车辆激活
- (void)sendCarActivationWith:(NSDate *)date target:(uint8_t)target isE20: (BOOL)isE20 successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 设备硬件绑定信息
// 设备软件绑信息定

// 关机重启休眠唤醒发送
- (void)sendCarTurnOffOrOnOrSleepWith:(uint8_t)type compleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 关机重启休眠唤醒确认
- (void)confirmCarTurnOffOrOnOrSleepWithCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 恢复出厂设置
- (void)setCarReviewWithGrade:(uint8_t)grade compleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 启动或关闭固件升级
- (void)writeCarUploadOpenOrCloseWithParam:(uint8_t)param successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 强制固件升级
- (void)setCarNeedUploadWithRank:(int)rank lowest:(NSString *)lowestVersion highest:(NSString *)highrstVersion successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取设备锁定及报警
- (void)getCarLockAlarmCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 设置设备锁定及报警
- (void)setCarLockAlarmWithParam:(uint8_t)param successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

//读取固件升级状态
- (void)getCarUploadStateCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 打开文件
- (void)openFileWithType:(uint8_t)openType fileName:(NSString *)fileName compleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入文件
- (void)writeFileWithHandle:(uint8_t)handle offset:(uint32_t)offset data:(NSData *)data compleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 读取文件
- (void)readFileWithHandle:(uint8_t)handle offset:(uint32_t)offset length:(uint8_t)length compleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 校验文件
- (void)readFileCheckWithHandle:(uint8_t)handle offset:(uint32_t)offset compleBlock:(IMNewCarModelCompletionBlock)compleBlock;
- (void)writeFileCheckWithHandle:(uint8_t)handle fileSize:(uint32_t)size offset:(uint32_t)offset checkCrc32:(uint32_t)crc32 compleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 关闭文件
- (void)closeFileWithHandle:(uint8_t)handle compleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 读取文件信息
- (void)readFileMessagaeWithName:(NSString *)fileName compleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 删除文件
- (void)deleteFileWithName:(NSString *)fileName successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 重命名文件
- (void)resetFileNameWithNewName:(NSString *)newName oldName:(NSString *)oldName successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 获取文件列表
- (void)getFileListWithNum:(uint16_t)num fileType:(NSString *)fileType compleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 解析文件列表 - 返回文件组字典
- (NSDictionary *)analyzeFileListWithData:(NSData *)data;

// 存储总容量及剩余容量
- (void)getRAMSizeWithNum:(uint8_t)num compleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 擦出m并格式化存储
- (void)deleteRAMWithNum:(uint8_t)num compleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 读取蓝牙名称
- (void)readBleNameCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入蓝牙名称
- (void)writeBleNameWithName:(NSString *)name successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 读取蓝牙密码
- (void)readBlePasswordCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 写入蓝牙密码
- (void)writeBlePasswordWithPassword:(NSData *)password successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// 读取蓝牙Mac地址
- (void)readBleMACAddressCompleBlock:(IMNewCarModelCompletionBlock)compleBlock;

// 验证蓝牙密码
- (void)checkBlePasswordWithPassword:(NSData *)password successBlock:(IMNewCarModelSettingSuccessBlock)success failBlock:(IMNewCarModelSettingFailBlock)fail;

// CRC32校验 -- 结果
- (uint32_t)crc32CheckWithData:(NSData *)data;

// 返回文件操作的错误提示语
- (NSString *)returnFileErrorStringWithCode:(int8_t)errorCode;


// 发送消息
- (void)sendMessageWithChannel:(uint8_t)channel property:(uint8_t)property dataParam:(NSData *)param isRead:(BOOL)isRead isRepeat:(BOOL)isRepeat repeatcount:(int)count compleBlock:(IMNewCarModelCompletionBlock)compleBlock ;
// 发送消息
- (void)sendMessageWithSource:(uint8_t)source target:(uint8_t)target channel:(uint8_t)channel property:(uint8_t)property dataParam:(NSData *)param isRead:(BOOL)isRead isRepeat:(BOOL)isRepeat repeatcount:(int)count compleBlock:(IMNewCarModelCompletionBlock)compleBlock;
@end

